package net.chasing.androidbaseconfig.util;

import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.net.Uri;
import android.os.Build;
import android.telephony.TelephonyManager;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

public class CheckUtils {
    /**
     * 是否是模拟器
     * 1:这是通过电池的伏数和温度来判断是真机还是模拟器
     * 模拟器的电池伏数可以为0或者是1000，而温度一定是0。但是真机的是可变的
     * 2:通过硬件信息进行过滤
     * 3:通过拨打电话进行过滤，大部分模拟器无法拨打电话
     * 4:通过CPU判断
     */
    public static boolean isEmulator(Context context) {
        try {
            IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
            Intent batteryStatusIntent;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
                batteryStatusIntent = context.registerReceiver(null, intentFilter, Context.RECEIVER_EXPORTED);
            else
                batteryStatusIntent = context.registerReceiver(null, intentFilter);
            if (batteryStatusIntent == null) return true;
            int voltage = batteryStatusIntent.getIntExtra("voltage", 99999);
            int temperature = batteryStatusIntent.getIntExtra("temperature", 99999);
            boolean isNoEmulator = temperature != 0 || voltage != 0 && voltage != 1000;
            if (!isNoEmulator) return true;
        } catch (Exception ignored) {
        }

        String url = "tel:" + "123456";
        Intent intent = new Intent();
        intent.setData(Uri.parse(url));
        intent.setAction(Intent.ACTION_DIAL);
        // 是否可以处理跳转到拨号的 Intent
        boolean canResolveIntent = intent.resolveActivity(context.getPackageManager()) != null;
        TelephonyManager systemService = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        boolean isEmulatorNetworkName = true;
        if (systemService != null) {
            isEmulatorNetworkName = systemService.getNetworkOperatorName().equalsIgnoreCase("android");
        }
        boolean isEmulator = Build.FINGERPRINT.startsWith("generic")
                || Build.FINGERPRINT.toLowerCase().contains("vbox")
                || Build.FINGERPRINT.toLowerCase().contains("test-keys")
                || Build.MODEL.contains("google_sdk")
                || Build.MODEL.contains("Emulator")
                || Build.MODEL.contains("MuMu")
                || Build.MODEL.contains("virtual")
                || Build.MODEL.contains("Android SDK built for x86")
                || Build.MANUFACTURER.contains("Genymotion")
                || (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
                || "google_sdk".equals(Build.PRODUCT)
                || isEmulatorNetworkName
                || !canResolveIntent;
        return isEmulator && noHaveLightSensor(context) || checkIsNotRealPhone();
    }

    private static boolean noHaveLightSensor(Context context) {
        SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
        if (sensorManager != null) {
            Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); //光
            return sensor == null;
        } else
            return true;
    }

    /**
     * 判断cpu是否为电脑来判断 模拟器
     *
     * @return true 为模拟器
     */
    private static boolean checkIsNotRealPhone() {
        String cpuInfo = readCpuInfo();
        return cpuInfo.contains("intel") || cpuInfo.contains("amd");
    }

    private static String readCpuInfo() {
        String result = "";
        try {
            String[] args = {"/system/bin/cat", "/proc/cpuinfo"};
            ProcessBuilder cmd = new ProcessBuilder(args);

            Process process = cmd.start();
            StringBuilder sb = new StringBuilder();
            String readLine;
            BufferedReader responseReader = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
            while ((readLine = responseReader.readLine()) != null) {
                sb.append(readLine);
            }
            responseReader.close();
            result = sb.toString().toLowerCase();
        } catch (Exception ignored) {
        }
        return result;
    }
}
